/*Mid窗体页面类*/
(function ($) {
    $.fn.yqDataGrid = function (opts, param) {
        if (typeof opts == 'string') {
            return $.fn.yqDataGrid.methods[opts](this, param);
        }

        var $this = this;
        var opt;
        if ($this.data("yqtype") == "yqDataGrid") {
            var $uniqueID = $this.attr("ID");
            var opts_ = $.extend({}, options($this));
            destroy($this);
            $this = $("#" + $uniqueID);
            opt = $.extend(opts_, opts);

            delete opt.toolbar;
        }
        else {
            opt = $.extend({}, $.fn.yqDataGrid.defaults, opts);
            var $uniqueID = $this.attr("ID");
            if ($uniqueID === undefined || $uniqueID === null || $uniqueID == "") {
                $uniqueID = $.getUniqueID();
                $this.attr("ID", $uniqueID);
            }
        }

        if (opt.width === undefined && $this.width() > 0) {
            opt.width = $this.width();
        }
        else if (typeof opt.width != "undefined") {
            $this.width(opt.width);
        }

        if (opt.height === undefined && $this.height() > 0) {
            opt.height = $this.height();
        }
        else if (typeof opt.height != "undefined") {
            $this.height(opt.height);
        }

        //转换编辑尺寸
        if (typeof opt.editModeW == "string") {
            var r_str = opt.editModeW.substring(opt.editModeW.length - 1, opt.editModeW.length);
            if (r_str == "%") {
                var wSacle = parseInt(opt.editModeW.substring(0, opt.editModeW.length - 1));
                opt.editModeW = parseInt(wSacle * $(window).width() / 100);
            } else {
                opt.editModeW = parseInt(opt.editModeW);
            }
        }
        if (typeof opt.editModeH == "string") {
            var r_str = opt.editModeH.substring(opt.editModeH.length - 1, opt.editModeH.length);
            if (r_str == "%") {
                var wSacle = parseInt(opt.editModeH.substring(0, opt.editModeH.length - 1));
                opt.editModeH = parseInt(wSacle * $(window).height() / 100);
            } else {
                opt.editModeH = parseInt(opt.editModeH);
            }
        }

        //---前处理，兼容输入设置错误
        if (opt.bindingKeyId == "") {
            opt.bindingKeyId = null;
        }
        if (opt.bindingValue == "") {
            opt.bindingValue = null;
        }
        if (opt.pKeyId == "") {
            opt.pKeyId = null;
        }
        if (opt.pKeyValue == "") {
            opt.pKeyValue = null;
        }

        if (opt.isPage && opt.move) {   //如果有分页，不能排序
            alert("id=" + $uniqueID + "设置了分页，不能调整顺序");
            opt.move = false;
        }

        opt.columns = [[]]; //表头对象
        opt.defaultEdit = opt.isEdit;
        opt.where = "";      //当前查询
        opt.prewhere = "*";  //上一个查询
        opt.fk_rows = [];  //外键集合
        //-------------------------

        opt.innerEdit_ = true;//外部删除、注销等操作附加按钮，默认是系统操作

        //组件加载结束
        opt.onload = true;
        //组件进程执行中
        opt.running = false;

        //变量信息
        $this.data("datagrid_opt", opt);
        $this.data("yqtype", "yqDataGrid");

        LoadJsCss($this, function () {
            get_columns($this);
        })
    };

    $.fn.yqDataGrid.defaults = {
        ajaxUrl: "/_db.html", //ajax地址
        dbname: null,
        tbname: null,
        keyId: "sid", //关键字段
        bindingKeyId: null,
        bindingValue: null,
        pKeyId: null,
        pKeyValue: null,

        tempno: -1,  //模板no
        titles: [],  //数据列配置对象
        data: {
            "error": 0,
            "info": "ok",
            "pageNumber": 1,
            "pageSize": 5,
            "pageCount": 0,
            "recordCount": 0,
            rows: []
        },
        loadData: false, //初始化加载数据

        frozenNum: 0, //锁定列数量（锁定左侧）
        fitColumns: false,  //自动扩展/收缩列宽度

        sumList: [],        //合计字段：a,b,c

        pageSize: 20,
        pageNo: 1,
        pageList: [5, 10, 20, 30, 40, 50],

        rownumbers: true,
        singleSelect: true,

        isPage: true, //分页
        addWhere: "", //附加条件
        where: "", //条件
        order: "sid", //排序

        editTitle: "编辑",//编辑窗体标题
        editMode: 2,    //1-自由编辑1（包含save按钮）,在当前行中编辑；
        //2-自由编辑2（包含save按钮），弹出编辑模态窗体
        //3-编辑（不包含save按钮），弹出编辑模态窗体
        //4-弹出模态窗体，独立编辑文件
        editType: 1,    //editMode=2,3时  1:属性编辑模式  2:form编辑模式
        editModeW: 600, //模态编辑器宽度 格式为 800（数字） 或 90%（窗体比例）
        editModeH: 450, //模态编辑器高度 格式为 600（数字）  或 90%（窗体比例）
        editMaximiz: false, //最大化显示
        editModeNo: -1, //编辑模板
        editUrl: null,     //编辑url

        moveModeW: 800, //模态编辑器宽度 格式为 800（数字）
        moveModeH: 600, //模态编辑器高度 格式为 600（数字）
        moveModeNo: 1,  //移动模板

        loadDefault: false,   //加载默认值
        blankTag: "*",        //值不能为空，标题附加标记

        menuType: 1,  //1-顶部菜单，2-右键菜单，3-顶部+右键  其他，无菜单
        dbClickEdit: true,
        btnMini: true, //按钮最小化
        isEdit: true, //可编辑
        copy: true,
        add: true,
        upp: true,
        del: true,
        isdel: false, //可注销
        isdel_field: "isdel", //注销使用的字段
        isdelEdit: true, //注销是否可编辑
        state: false,   //可状态编辑
        state_field: "state",//状态字段
        wflock: false,        //可流程控制
        move: false, //可移动
        toexcel: false, //Excel导出
        excelName: "excel导出",   //Excel导出文件名
        inexcel: false, //Excel导入
        editLinks: [],  //显示的链接菜单
        editMenus: [],  //显示在其它中的菜单
        popMenuWidth: 150,     //右键菜单第一层宽度

        editAlert: true,  //删除、注销提醒
        editLoadData: false, //添加、修改后更新数据库数据

        ddSeeks: [],    //下拉查询字段，字段名称
        isSimple: true, //简单查询
        txtSeeks: [],   //简单查询字段，字段名称
        isSimpleDDLW: 120, //简单查询选择项目宽度
        isSimpleTxtW: 160, //简单查询输入值宽度

        isSeek: true,  //高级查询
        seekNo: -1,     //查询模板编码
        seekModeW: 600,
        seekModeH: 400,
        editLinks_r: [],  //右侧附加菜单

        linkField: [],    //连接字段
        linkBlank: "[link]", //空连接显示

        verId: null,

        checkBoxCol: false,   //行选择复选框
        checkBoxFormatter: function (value, row, index) {  //选择渲染事件,true 渲染
            return true;
        },
        checkBoxChecked: function (checkCount) {  //行选择事件 选择的数量
            //console.log("checkCount", checkCount);
        },
        checkBoxChange: function (row, checked) {
            //console.log("checkBoxChange", row, checked);
        },   //选择事件 行，是否选中

        beforeBindingTitle: function (titles, callback) {
            callback(titles);
        }, //标题绑定前
        afterBindingTitle: function () { }, //标题绑定后
        beforeLoadData: function (opts, callback) {   //opts：查询参数，data：未null时，默认查询；不是null，外部查询
            var data = null;
            callback(opts, data);
        },
        beforeSetdata: function (data, callback) {
            callback(data)
        }, //绑定数据之前
        afterSetdata: function (data) { }, //绑定数据之后

        uppActionState: function (s_index, s_row, callback) {     //操作节点状态处理接口
            callback(true);   //返回 true ，启用右键菜单
        },

        onBeforeEdit: function (index, row) {
            //console.log(" opt_dg.onBeforeEdit",index,row);
        },    //editMode: 1,  自由编辑 生效
        onAfterEdit: function (index, row, changes) {
            //console.log(" opt_dg.onAfterEdit",index,row,changes);
        },  //editMode: 1,  自由编辑 生效

        btnAction: function (action, params, callback) {   //头部菜单执行动作，返回true为执行默认选择操作
            callback(true);
        },

        beforeSave: function (d_rows, callback) {    //保存前判断，返回true执行保存操作
            callback(true, d_rows);
        },

        onBeforeShowEdit: function (titles, action, row, callback) {      //add/upp/move 编辑执行前
            callback(true, titles, row);      //true 执行编辑
        },
        beforeDataAction: function (d_rows, callback) {    //修改之前，true 执行
            callback(true, d_rows);
        },
        afterDataAction: function (rows, res) {    //修改之后
        },

        onClickRow: function (index, row) {     //点击行
        },

        beforeToExcel: function (title, rows, mergeCells, callback) { //Excel导出前数据处理
            callback(title, rows, mergeCells);
        },

        copyText: "Copy",
        addText: "Add",
        uppText: "Upp",
    };

    $.fn.yqDataGrid.methods = {
        options: function (jq) {
            return options(jq);
        },
        destroy: function (jq) {
            destroy(jq);
        },
        isEdit: function (jq, tf) {
            isEdit(jq, tf);
        },
        resize: function (jq, res) {
            var opt = options(jq);
            if (res.width === undefined) {
                res.width = opt.width;
            }
            if (res.height === undefined) {
                res.height = opt.height;
            }

            resize(jq, res.width, res.height);
        },
        toolbar: function (jq) {
            return options(jq).toolbar;
        },
        getBtns: function (jq, id) {
            return options(jq).toolbar.yqEditMenu("getBtns", id);
        },
        btnEnable: function (jq, id) {
            var toolbar = options(jq).toolbar;
            if (typeof toolbar != "undefined") {
                toolbar.yqEditMenu("enable", id);
            }
        },
        btnDisable: function (jq, id) {
            var toolbar = options(jq).toolbar;
            if (typeof toolbar != "undefined") {
                toolbar.yqEditMenu("disable", id);
            }
        },
        setBindingValue: function (jq, bindingValue) {
            var opt = options(jq);
            opt.bindingValue = bindingValue;
            opt.prewhere = "*";
            uppActionState(jq);
        },
        setPKeyValue: function (jq, pKeyValue) {
            var opt = options(jq);
            opt.pKeyValue = pKeyValue;
            opt.prewhere = "*";
        },
        clear: function (jq, data) {
            setData(jq, { rows: [] });
        },
        loadData: function (jq) {
            loadData(jq);
        },
        setData: function (jq, data) {
            setData(jq, data);
        },
        seek: function (jq, where) {                 //查询数据
            if (where === undefined) {
                where = "";
            }
            seek(jq, where);
        },
        reSeek: function (jq) {               //重新加载数据
            reSeek(jq);
        },

        endEditing: function (jq) {              //自由编辑，完成编辑
            return endEditing(jq);
        },

        updateRow: function (jq, param) { //{"index":1,"row":{}}  修改行,兼容 row
            var opt = options(jq);

            if (param.index === undefined) {
                var _select = false;
                for (var i = 0; i < opt.data.rows.length; i++) {
                    if (opt.data.rows[i][opt.keyId] == param[opt.keyId]) {
                        var _param = { "index": i, "row": $.extend({}, param) };
                        param = _param;
                        _select = true;
                        break;
                    }
                }

                if (!_select) {
                    jq.yqDataGrid("appendRow", param);
                    return;
                }
            }

            if (opt.editMode == 1 || opt.editMode == 2) {
                if (endEditing(jq)) {
                    jq.datagrid("updateRow", param);
                }
            } else {
                jq.datagrid("updateRow", param);
                uppActionState(jq, param.index, param.row);
            }
        },
        appendRow: function (jq, row) { //添加行
            var $object = jq;
            var opt = options($object);

            if (!(opt.bindingKeyId === null) && !(opt.bindingValue === null)) {
                row[opt.bindingKeyId] = opt.bindingValue;
            }
            if (!(opt.pKeyId === null) && !(opt.pKeyValue === null)) {
                row[opt.pKeyId] = opt.pKeyValue;
            }

            if (opt.editMode == 1 || opt.editMode == 2) {
                var _tag = row["_tag"];
                row = $.yqFmToView(row, opt.titles);
                if (typeof _tag != "undefined") {
                    row["_tag"] = _tag;
                }
            } else {
                row = $.yqFmToView(row, opt.titles);

            }

            appendRow($object, row);
        },
        deleteRow: function (jq, i) {  //删除行
            if (typeof i == "number") {
                deleteRow_(jq, i);
            } else if (typeof i === 'object' && i !== null) {
                var opt = options(jq);
                var _i = -1;
                for (var _i = 0; _i < opt.data.rows.length; _i++) {
                    if (opt.data.rows[_i][opt.keyId] == i[opt.keyId]) {
                        deleteRow_(jq, _i);
                        break;
                    }
                }
            }
        },

        addRow: function (jq, row) { //添加行(进行数据库数据添加处理)
            rowEdit(jq, "add", row);
        },
        showEdit: function (jq, sid) { //添加行(进行数据库数据添加处理)
            var opt = options(jq);
            var rows = opt.data.rows;
            var s_index = -1;
            for (var i = 0; i < rows.length; i++) {
                if (rows[i][opt.keyId] == sid) {
                    s_index = i;

                    break;
                }
            }

            if (s_index === -1) {
                return;
            }

            jq.datagrid("selectRow", s_index);
            btn_upp(jq);
        },
        uppRow: function (jq, row) { //修改行(进行数据库数据修改处理)
            rowEdit(jq, "upp", row);
        },
        delRow: function (jq, index) { //删除行(进行数据库数据删除处理)
            options(jq).innerEdit_ = false;
            del_run(jq, index);
        },

        uppActionState: function (jq) {    //更新按钮状态         
            uppActionState(jq);
        },
        getRows: function (jq) {                         //取得行数据
            return getRows(jq);
        },
        getSelected: function (jq) {
            return jq.datagrid("getSelected");
        },
        getSelectedIndex: function (jq) {
            var $object = jq;
            var row = $object.datagrid("getSelected");
            if (row == null) {
                return -1;
            }
            return $object.datagrid("getRowIndex", row);
        },
        dataAction: function (jq, d_rows) {            //执行操作
            dataAction(jq, d_rows);
        },
        setField: function (jq, para) {
            if (para === undefined) {
                return;
            }
            if (para.name === undefined) {
                return;
            }
            if (para.value === undefined) {
                return;
            }

            setfield(jq, para.name, para.value)
        },
        loading: function (jq) {
            var $object = jq;
            $object.datagrid("loading");
        },
        loaded: function (jq) {
            var $object = jq;
            $object.datagrid("loaded");
        },

        checkAll: function (jq, checked) { //全部选择、不选择
            var opt = options(jq);
            var $yq_checkbox = jq.closest('div.datagrid-view').find(".yq_checkbox");
            $yq_checkbox.prop("checked", checked);
            var checkCount = $yq_checkbox.filter(":checked").length;
            opt.checkBoxChecked.call(jq, checkCount);

            var rows = jq.datagrid("getRows");
            for (var i = 0; i < $yq_checkbox.length; i++) {
                var index = parseInt($($yq_checkbox[i]).attr("tag"));
                opt.checkBoxChange.call(jq, rows[index], $yq_checkbox[i].checked);
            }
        },
        checkBoxRows: function (jq) {   //取得多选行的数据
            var $yq_checkbox = jq.closest('div.datagrid-view').find(".yq_checkbox");
            var rows = jq.datagrid("getRows");
            var _rows = [];
            for (var i = 0; i < $yq_checkbox.length; i++) {
                var index = parseInt($($yq_checkbox[i]).attr("tag"));
                if ($yq_checkbox[i].checked) {
                    _rows.push($.extend({}, rows[index]));
                }
            }
            return _rows;
        },
        setCheckBoxRow: function (jq, param) { //设置checkbox按钮是否选中
            var $yq_checkbox = jq.closest('div.datagrid-view').find(".yq_checkbox");
            for (var i = 0; i < $yq_checkbox.length; i++) {
                var $ck = $($yq_checkbox[i]);
                var index = parseInt($ck.attr("tag"));
                if (index == param.index) {
                    $ck.prop("checked", param.checked);
                    $ck.trigger('change');
                    break;
                }
            }
        },
        /*
        合并单元格，options包含以下属性：
        index：行索引。
        field：字段名称。
        rowspan：合并的行数。
        colspan：合并的列数。
        */
        mergeCells: function (jq, param) {
            jq.datagrid("mergeCells", param);
        }
    };

    function LoadJsCss($object, callback) {
        var opt = options($object);
        var file = [];
        file.push({ url: "/scripts/crypto/sha256.min.js", type: "js" });
        $.yqLoadJsCss(file, function () {
            callback();
        })
    }

    function options($object) {
        return $object.data("datagrid_opt");
    }

    function form_load($object) {
        var opt = options($object);
        opt.onload = false;
        opt.afterBindingTitle.call($object);

        opt.prevent_e = {};
        opt.prevent_e.clientX = 0;
        opt.prevent_e.clientY = 0;
        opt.prevent_e.id = $object.attr("id");
        opt.prevent_e.options = opt;

        var $body = $object.closest('div.datagrid-view').find(".datagrid-body");
        $body.bind('click', function (event) {
            opt.prevent_e.clientX = event.clientX;
            // // 在控制台输出坐标  
            // console.log('点击位置：(' + event.clientX + ', ' + event.clientY + ')',opt.prevent_e);
        });
    }

    function destroy($object) {
        var opt = options($object);

        var $body = $object.closest('div.datagrid-view').find(".datagrid-body");
        $body.unbind('click');

        var $dg = $object.closest('div.datagrid');
        var $new_obj = $($object.prop("outerHTML"));
        var toolbar = opt.toolbar;
        if (typeof toolbar != "undefined") {
            toolbar.yqEditMenu("destroy");
        }
        $new_obj.show();
        var id = $object.attr("id");
        $new_obj.removeAttr("id");
        $dg.before($new_obj);
        $dg.remove();
        $new_obj.attr("id", id);
        $new_obj.removeClass("datagrid-f");

        $object.removeData("datagrid_opt");
        $object.removeData("yqtype");
    }

    function isEdit($object, tf) {
        var opt = options($object);
        opt.isEdit = tf;

        uppActionState($object);
    }

    function get_columns($object) {
        var opt = options($object);

        if (opt.titles.length > 0) {
            init_linkField($object);
            opt.titles = $.yqFmUiTitle(opt.titles);
            opt.beforeBindingTitle.call($object, opt.titles,
                function (_titles) {
                    opt.titles = _titles;
                    opt.columns = $.yqDgColumns.call($object, opt.titles);
                    init_dg($object);
                });
        }
        else {
            var pp_opt = {
                ajaxUrl: opt.ajaxUrl,
                dbname: opt.dbname,                //数据库
                tbname: opt.tbname,                //表
                tempno: opt.tempno
            };

            if (typeof opt._appno != undefined) {
                pp_opt.ctrlid = opt._ctrlid;
                pp_opt.appno = opt._appno;
                pp_opt.menuno = opt._menuno;
            }

            $.yqTbTitle(pp_opt, function (res) {
                if (res.error == 0) {
                    opt.titles = $.yqFmUiTitle(res.titles);
                    init_linkField($object);

                    opt.beforeBindingTitle.call($object, opt.titles,
                        function (_titles) {
                            opt.titles = _titles;
                            opt.columns = $.yqDgColumns.call($object, opt.titles);
                            init_dg($object);
                        });
                }
                else {
                    console.log(res);
                    $.yqMessager("error", res.info + "[" + res.error + "]");
                }
            })
        }

        // else {
        //     opt.beforeBindingTitle.call($object, opt.columns,
        //         function (columns) {
        //             opt.columns = columns;
        //             init_dg($object);
        //         });
        // }
    }

    //格式化编辑连接字段
    function init_linkField($object) {
        var opt = options($object);
        if (opt.editMode == 1) {
            return;
        }

        if (opt.linkField.length > 0) {
            for (var i = 0; i < opt.linkField.length; i++) {
                for (var j = 0; j < opt.titles.length; j++) {
                    if (opt.linkField[i] == opt.titles[j].name) {
                        if (typeof opt.linkBlank == "function") {
                            opt.titles[j].linkBlank = opt.linkBlank;
                        } else {
                            opt.titles[j].linkBlank = function (value, row, index) {
                                if (!(row["_footer_"] === undefined)) { //_footer_ 有汇总标记
                                    return "";
                                }

                                return '<a class="link" href="javascript:$(\'#' + this.attr("id") + '\').yqDataGrid(\'showEdit\',\'' + row[opt.keyId] + '\')">' + value + '</a>'
                            };
                        }

                        break;
                    }
                }
            }
        }
    }

    function init_dg($object) {
        var opt = options($object);
        frozenNum = opt.frozenNum;

        if (opt.defaultEdit && (opt.editMode == 1 || opt.editMode == 2)) {  //自由编辑，第一个位置添加tag标记
            opt.columns[0].unshift({
                title: "",
                field: "_tag",
                width: 20,
                ui_mask: {},
                align: 'center',
                styler: function (value, row, index) {
                    return 'background-color:#efefef;color:red;';
                }
            });

            frozenNum += 1;
        }

        if (opt.checkBoxCol) {
            opt.singleSelect = true;

            frozenNum += 1;
            opt.columns[0].unshift({
                title: '<input type="checkbox" onchange="$(\'#' + $object.attr("id") + '\').yqDataGrid(\'checkAll\',this.checked)"></input>',
                field: '_my_checkbox',
                width: 30,
                formatter: function (value, row, index) {
                    if (row["_footer_"] === undefined && opt.checkBoxFormatter.call($object, value, row, index)) {
                        var $yq_checkbox = $object.closest('div.datagrid-view').find(".yq_checkbox");
                        if ($yq_checkbox.length > 0 && $yq_checkbox.length >= index) {
                            if ($yq_checkbox[index].checked) {
                                return '<input class="yq_checkbox" type="checkbox" tag="' + index + '" checked></input>';
                            }
                        }
                        return '<input class="yq_checkbox" type="checkbox" tag="' + index + '"></input>';
                    } else {
                        return '';
                    }
                }
            });
        }

        //console.log("opt.columns", opt.columns);

        var opt_dg = {
            columns: opt.columns,
            rownumbers: opt.rownumbers,
            singleSelect: opt.singleSelect,

            onLoadSuccess: function (data) {
                $(this).datagrid("loaded");
                var opt = options($(this));
                opt.running = false;

                if (opt.checkBoxCol) {
                    var $yq_checkbox = $object.closest('div.datagrid-view').find(".yq_checkbox");
                    $yq_checkbox.unbind();
                    $yq_checkbox.bind("change", function () {
                        var checkCount = $yq_checkbox.filter(":checked").length;
                        opt.checkBoxChecked.call($object, checkCount);

                        var rows = $object.datagrid("getRows");
                        var index = parseInt($(this).attr("tag"));
                        opt.checkBoxChange.call($object, rows[index], this.checked);
                    });
                }


                opt.afterSetdata.call($object, data);
                if (opt.onload) {
                    form_load($object);
                }

                if (opt.isPage) {
                    var pager = $(this).datagrid('getPager');
                    pager.pagination('refresh', {
                        total: opt.data.recordCount,    //;
                        pageNumber: opt.data.pageNo
                    });
                }

                uppActionState($(this));

                opt.onClickRow.call($object, -1, null);
            },
            onClickRow: function (index, row) {
                var $row = $(this).parent().find(".datagrid-row-selected");
                if ($row.length > 0) {
                    var prevent_e = $.getPreventDefault($row[$row.length - 1]);
                    opt.prevent_e.clientY = prevent_e.clientY;
                }

                opt.prevent_e.id = $object.attr("id");
                opt.prevent_e.options = opt;

                uppActionState($(this), index, row, function (tf) {
                });

                opt.onClickRow.call($object, index, row);
            },
        };

        if (opt.checkBoxCol) {
            opt_dg.checkOnSelect = false;
            opt_dg.selectOnCheck = false;
        };

        if (opt.sumList.length > 0) {
            var hasFooter = false;
            for (var i = 0; i < opt.sumList.length; i++) {
                var name = opt.sumList[i];
                for (var j = 0; j < opt.titles.length; j++) {
                    if (opt.titles[j].name == name && opt.titles[j].ui_visible) {
                        hasFooter = true;
                        break;
                    }
                }
                if (hasFooter) {
                    break;
                }
            }

            opt.showFooter = hasFooter;
            opt_dg.showFooter = hasFooter;
        }

        if (opt.isPage) {
            opt_dg.pagination = true;  //显示分页
            opt_dg.pageNumber = opt.pageNo;
            opt_dg.pageSize = opt.pageSize;

            var pageList = opt.pageList;
            for (var i = 0; i < pageList.length; i++) {
                if (pageList[i] > opt.pageSize) {
                    pageList.splice(i, 0, opt.pageSize);
                    break;
                }
            }
            if (pageList[pageList.length - 1] < opt.pageSize) {
                pageList.push(opt.pageSize)
            }
            opt_dg.pageList = pageList;
        }

        if (frozenNum > 0 && frozenNum < opt.columns[0].length) {
            var columns_0 = $.extend([], opt.columns[0]);
            var f_columns = [];
            for (var i = 0; i < frozenNum; i++) {
                f_columns.push($.extend({}, columns_0[i]));
            }

            columns_0.splice(0, frozenNum);

            if (opt.columns.length == 1) {
                opt_dg.columns = [columns_0];
            }
            else {
                opt_dg.columns = [columns_0, opt.columns[1]];
            }

            opt_dg.frozenColumns = [f_columns];
        }

        if (opt.editMode == 1) {
            opt.editIndex = undefined;
            opt_dg.onClickCell = onClickCell;

            opt_dg.onBeforeEdit = function (index, row) {
                $(this).datagrid("options").editRunIndex = index;
                $(this).datagrid("options").editRunRow = row;

                $(this).yqDataGrid("options").onBeforeEdit.call($(this), index, row);
            };

            opt_dg.onEndEdit = onEndEdit;

            opt_dg.onAfterEdit = function (index, row, changes) {
                $(this).yqDataGrid("options").onAfterEdit.call($(this), index, row, changes);
            };
        }
        else if (opt.editMode != 1 && opt.dbClickEdit) {
            opt_dg.onDblClickRow = function (index, row) {
                console.log("dbClickEdit");
                btnAction($object, "upp");
            }
        }

        // ddSeeks: [],    //下拉查询字段，字段名称
        // isSimple: true, //简单查询
        // txtSeeks: [],   //简单查询字段，字段名称
        // isSimpleDDLW: 260, //简单查询选择项目宽度
        // isSimpleTxtW: 260, //简单查询输入值宽度

        // isSeek: false,  //高级查询
        // seekNo: -1,     //查询模板编码

        //editLinks_r: []

        if (typeof opt.toolbar == "object") {
            opt_dg.toolbar = opt.toolbar;
        } else if ((opt.defaultEdit && (opt.copy ||
            opt.add || opt.upp || opt.del || opt.isdel || opt.state
            || opt.move || opt.inexcel)) ||
            opt.toexcel ||
            opt.editLinks.length > 0 ||
            opt.editMenus.length > 0 ||
            opt.ddSeeks.length > 0 ||
            opt.isSimple ||
            opt.isSeek ||
            opt.editLinks_r.length > 0
        ) {
            var $toolbar = $("<div></div>");
            opt.toolbar = $toolbar;
            opt_dg.toolbar = $toolbar;
            $object.after($toolbar);

            opt_dg.onRowContextMenu = function (e, index, row) {
                if (opt.menuType == 2 || opt.menuType == 3) {
                    uppActionState($object, index, row, function (tf) {
                        if (tf) {
                            e.preventDefault();
                            opt.toolbar.yqEditMenu("open", e);
                        }
                    });
                }
            }

            var menu_opt = {
                ajaxUrl: opt.ajaxUrl,
                type: opt.menuType,  //1(!=2或3)-顶部菜单，2-右键菜单，3-顶部+右键
                mini: opt.btnMini,
                copy: opt.defaultEdit && opt.copy,
                addroot: false,
                add: opt.defaultEdit && opt.add,
                upp: opt.defaultEdit && (opt.upp && opt.editMode != 1),
                del: opt.defaultEdit && opt.del,
                toexcel: opt.toexcel,
                inexcel: opt.defaultEdit && opt.inexcel,
                save: opt.defaultEdit && (opt.editMode == 1 || opt.editMode == 2),
                isdel: opt.defaultEdit && opt.isdel,
                state: opt.defaultEdit && opt.state,
                state_field: opt.state_field,
                cut: false,
                move: opt.defaultEdit && opt.move,
                links: opt.editLinks,  //显示的链接菜单
                menus: opt.editMenus,  //显示在其它中的菜单
                width: opt.popMenuWidth, //右键菜单第一层宽度

                titles: opt.titles,         //
                ddSeeks: opt.ddSeeks,      //下拉查询字段，字段名称
                isSimple: opt.isSimple,    //简单查询
                txtSeeks: opt.txtSeeks,    //简单查询字段，字段名称
                isSimpleDDLW: opt.isSimpleDDLW, //简单查询选择项目宽度
                isSimpleTxtW: opt.isSimpleTxtW, //简单查询输入值宽度

                isSeek: opt.isSeek,  //高级查询
                seekModeW: opt.seekModeW,
                seekModeH: opt.seekModeH,

                links_r: opt.editLinks_r,
                afterBindingTitle: function () {
                    init_dg_2($object, opt_dg);
                }, //标题绑定后
                onClick: function (action, params) {      //按钮点击事件，action为操作id
                    btnAction($object, action, params);
                },
                onSeek: function (where, order) {           //查询
                    opt.order = order;
                    seek($object, where);
                }
            };

            if (opt.isSimple || opt.isSeek) {
                getSeekTitles($object, function (titles) {
                    menu_opt.titles = titles;
                    $toolbar.yqEditMenu(menu_opt);
                });
            } else {
                $toolbar.yqEditMenu(menu_opt);
            }

            return;
        }

        init_dg_2($object, opt_dg);
    }

    function init_dg_2($object, opt_dg) {
        var opt = options($object);

        $object.datagrid(opt_dg);

        if (opt.isPage) {
            var $pager = $object.datagrid('getPager');
            $pager.pagination({
                onSelectPage: function (pageNo, pageSize) {
                    opt.pageSize = pageSize;
                    opt.pageNo = pageNo;
                    //console.log(pageNo, pageSize);
                    loadData($object);
                }
            });
        }

        if (opt.data.rows.length > 0) {
            setData($object, opt.data)
        }
        else if (opt.loadData) {
            loadData($object);
        }
        else {
            uppActionState($object, -1, null, function (tf) { });
            form_load($object);
        }
    }

    //重新加载数据
    function reSeek($object) {
        var opt = options($object);
        opt.prewhere = "*";
        loadData($object);
    }

    //查询
    function seek($object, where) {
        var opt = options($object);
        if (opt.prewhere == where) {
            return;
        }

        opt.where = where;
        loadData($object);
    }

    //加载数据
    function loadData($object) {
        var opt = options($object);
        if ((!(opt.bindingKeyId === null) && opt.bindingValue === null) ||
            (!(opt.pKeyId === null) && opt.pKeyValue === null)) {
            if (!opt.onload) {
                setData($object, { rows: [] });
            }

            return;
        }

        if (opt.running) {
            return;
        }

        opt.running = true;
        opt.prewhere = opt.where;
        if (opt.where === null) {
            opt.where = "";
        }
        var l_where = opt.where;

        if (!(opt.addWhere === null) && opt.addWhere != "") {
            if (l_where == "") {
                l_where = opt.addWhere;
            } else {
                l_where = "(" + l_where + ") and (" + opt.addWhere + ")";
            }
        }

        var bindWhere = "";
        if (!(opt.bindingKeyId === null) && !(opt.bindingValue === null)) {
            bindWhere = opt.bindingKeyId + " = '" + opt.bindingValue + "'";
        }
        if (!(opt.pKeyId === null) && !(opt.pKeyValue === null)) {
            bindWhere += (bindWhere == "" ? "" : " and ") + opt.pKeyId + "='" + opt.pKeyValue + "'";
        }

        if (bindWhere != "") {
            if (l_where == "") {
                l_where = bindWhere;
            } else {
                l_where = "(" + l_where + ") and (" + bindWhere + ")";
            }
        }

        $object.datagrid("loading");
        if (opt.isPage) {
            var p_opt = {
                ajaxUrl: opt.ajaxUrl,
                dbname: opt.dbname,
                tbname: opt.tbname,
                where: l_where,
                order: opt.order,
                pagesize: opt.pageSize,
                pageno: opt.pageNo
            };

            if (typeof opt._appno != undefined) {
                p_opt.ctrlid = opt._ctrlid;
                p_opt.appno = opt._appno;
                p_opt.menuno = opt._menuno;
            }

            opt.beforeLoadData.call($object, p_opt,
                function (_p_opt, _data) {
                    if (_data === null) {
                        $.yqDbTbPaging(_p_opt, function (data) {
                            //console.log("aaaa", data);
                            if (data.error == 0) {
                                setData($object, data)
                            }
                            else {
                                opt.running = false;
                                $object.datagrid("loaded");
                                if (opt.onload) {
                                    form_load($object);
                                }
                            }
                        });
                    } else {
                        if (_data.error == 0) {
                            setData($object, _data)
                        }
                        else {
                            opt.running = false;
                            $object.datagrid("loaded");
                            if (opt.onload) {
                                form_load($object);
                            }
                        }
                    }
                });
        }
        else {
            var p_opt = {
                ajaxUrl: opt.ajaxUrl,
                dbname: opt.dbname,
                tbname: opt.tbname,
                where: l_where,
                order: opt.order
            };
            if (typeof opt._appno != undefined) {
                p_opt.ctrlid = opt._ctrlid;
                p_opt.appno = opt._appno;
                p_opt.menuno = opt._menuno;
            }

            opt.beforeLoadData.call($object, p_opt,
                function (_p_opt, _data) {
                    if (_data == null) {
                        $.yqDbTbSelect(_p_opt, function (data) {
                            if (data.error == 0) {
                                setData($object, data)
                            }
                            else {
                                opt.running = false;
                                $object.datagrid("loaded");
                                if (opt.onload) {
                                    form_load($object);
                                }
                            }
                        });
                    } else {
                        if (_data.error == 0) {
                            setData($object, _data)
                        }
                        else {
                            opt.running = false;
                            $object.datagrid("loaded");
                            if (opt.onload) {
                                form_load($object);
                            }
                        }
                    }
                });
        }
    }

    function setData($object, data) {
        var opt = options($object);
        opt.running = true;
        $object.datagrid("loading");

        data.rows = $.yqFmToViews(data.rows, opt.titles);

        if (opt.sumList.length > 0 && opt.showFooter) {
            var footer = {
                "_footer_": true
            };
            for (var j = 0; j < opt.sumList.length; j++) {
                footer[opt.sumList[j]] = 0;
            }
            for (var i = 0; i < data.rows.length; i++) {
                for (var j = 0; j < opt.sumList.length; j++) {
                    var name = opt.sumList[j];
                    var num = data.rows[i][name];
                    try {
                        num = ((num === undefined || num === null) ? 0 : parseFloat(num));
                        if (isNaN(num)) {
                            num = 0;
                        }
                    } catch (err) {
                        num = 0;
                    }
                    footer[name] += num;
                }
            }
            data.footer = [footer];
        }

        setForienKeys($object, data.rows,
            function () {
                opt.beforeSetdata.call($object, data, function (_data) {
                    opt.data = _data;

                    var data_ = $.extend({}, _data);
                    var rows_ = [];
                    _data.rows.forEach(row => {
                        rows_.push($.extend({}, row))
                    });

                    data_.rows = rows_;

                    if (opt.isPage) {
                        $object.datagrid("options").pageNumber = data_.pageNo;
                    }

                    $object.datagrid("loadData", data_);
                });
            });
    }

    //外键处理
    function setForienKeys($object, rows, callback) {
        var opt = options($object);
        var opts = {
            "ajaxUrl": opt.ajaxUrl,
            "rows": rows,
            "titles": opt.titles,
            "fk_rows": opt.fk_rows === undefined ? [] : opt.fk_rows
        };

        if (typeof opt._appno != undefined) {
            opts.ctrlid = opt._ctrlid;
            opts.appno = opt._appno;
            opts.menuno = opt._menuno;
        }

        $.yqGetForeignkeys(opts,
            function (fk_rows) {
                opt.fk_rows = fk_rows;
                callback();
            });
    }

    function setfield($object, field, val) {
        var opt = options($object);

        var index = $object.datagrid("options").editRunIndex;
        if (index === undefined) {
            return;
        }

        if (val === undefined) {
            val = null;
        }

        if (index < opt.data.rows.length) {
            if (val === null) {
                delete opt.data.rows[index][field];
            } else {
                opt.data.rows[index][field] = val;
            }
        }

        var $editor = $object.datagrid("getEditor",
            {
                index: index,
                field: field
            });

        if ($editor === null) {
            var row = $object.datagrid("getRowIndex", index);
            if (val === null) {
                delete row[field];
            } else {
                row[field] = val;
            }
            var $td = $object.closest('div.datagrid-view')
                .find(".datagrid-view2")
                .find('tr[datagrid-row-index="' + index + '"]')
                .find('td[field="' + field + '"]');
            if ($td.length > 0) {
                $td.find('div').html(val);
                $object.datagrid("options").editRunRow[field] = val;
                //$object.datagrid("options").data.rows[index][field] = val;
            }
        } else {
            $.yqDgEditorSetValue($editor.target, val)
        }
    }


    //---------------------------
    function onClickCell(index, field) {
        var $object = $(this);
        var opt = options($object);

        var s_row = $object.datagrid("getRows")[index];
        if (s_row["_tag"] == "D") {
            return;
        }

        if (opt.editIndex != index) {
            if (!endEditing($object)) {
                delete opt.editIndex;
            }
        }

        $object.datagrid('selectRow', index)
            .datagrid('beginEdit', index);
        var ed = $object.datagrid('getEditor', { index: index, field: field });
        if (ed) {
            ($(ed.target).data('textbox') ? $(ed.target).textbox('textbox') : $(ed.target)).focus();
        }
        opt.editIndex = index;
    }

    function endEditing($object) {
        var opt = options($object);

        if (opt.editIndex === undefined) { return true }
        if ($object.datagrid('validateRow', opt.editIndex)) {
            $object.datagrid('endEdit', opt.editIndex);
            opt.editIndex = undefined;
            return true;
        } else {
            return false;
        }
    }

    function onEndEdit(index, row) {
        //取得值
        var $object = $(this);
        var opt = options($(this));

        delete opt.editRunIndex;
        delete opt.editRunRow;

        if (index < opt.data.rows.length) {    //修改判断
            delete row["_tag"];
            if ($.isRowEqual(row, opt.data.rows[index]) == false) {
                row["_tag"] = "U";
            }
            else {
                row["_tag"] = null;
            }

            $object.datagrid("updateRow", { index: index, row: row });
        }
    }

    function btnAction($object, action, params) {
        var opt = options($object);

        if (params === undefined) {
            params = {};
        }

        opt.btnAction.call($object, action, params,
            function (tf) {
                if (tf) {
                    opt.innerEdit_ = true;
                    const actionHandlers = {
                        "copy": btn_copy,
                        "add": btn_add,
                        "upp": btn_upp,
                        "del": btn_del,
                        "save": btn_save,
                        "undo": btn_undo,
                        "isdel1": (obj) => btn_isdel(obj, true),
                        "isdel0": (obj) => btn_isdel(obj, false),
                        "state": (obj) => btn_state(obj, params),
                        "move": btn_move,
                        "toexcel": btn_toexcel,
                        "inexcel": btn_inexcel
                    };

                    if (action in actionHandlers) {
                        actionHandlers[action]($object);
                    } else {
                        console.warn("未知的操作: ", action); // 添加默认处理逻辑
                    }
                }
            });
    }

    function resize($object, width, height) {
        var opt = options($object);
        opt.width = width;
        opt.height = height;
        $object.datagrid("resize", {
            width: width,
            height: height
        });
    }

    //取得行数据
    function getRows($object) {
        var rows = $object.datagrid("getRows");
        return rows;
    }

    // copy: true,
    // add: true,
    // upp: true,
    // del: true,
    // isdel: false, //可注销
    // isdelEdit: true, //注销是否可编辑
    // move: true, //可移动
    // toexcel: true,
    // inexcel: true,


    //更新操作状态信息
    function uppActionState($object, s_index, s_row, callback) {
        var opt = options($object);

        if (s_index === undefined || s_row === undefined) {
            s_row = $object.datagrid("getSelected");
            s_index = -1;
            if (!(s_row === null)) {
                s_index == $object.datagrid("getRowIndex", s_row);
            }
        }

        if (!(opt.bindingKeyId === null) && opt.bindingValue === null) {
            if (opt.copy) {
                opt.toolbar.yqEditMenu("disable", "copy");
            }
            if (opt.add) {
                opt.toolbar.yqEditMenu("disable", "add");
            }
            if (opt.upp) {
                opt.toolbar.yqEditMenu("disable", "upp");
            }
            if (opt.del) {
                opt.toolbar.yqEditMenu("disable", "del");
            }
            if (opt.isdel) {
                opt.toolbar.yqEditMenu("disable", "isdel1");
                opt.toolbar.yqEditMenu("disable", "isdel0");
            }
            if (opt.state) {
                opt.toolbar.yqEditMenu("disable", "state");
            }
            if (opt.move) {
                opt.toolbar.yqEditMenu("disable", "move");
            }

            if (opt.toexcel) {
                opt.toolbar.yqEditMenu("disable", "toexcel");
            }

            if (opt.inexcel) {
                opt.toolbar.yqEditMenu("disable", "inexcel");
            }

            if (opt.editMode == 1 || opt.editMode == 2) {
                opt.toolbar.yqEditMenu("disable", "save");
                opt.toolbar.yqEditMenu("disable", "undo");
            }

            opt.uppActionState.call($object, s_index, s_row, function (tf) {     //操作节点状态处理接口
                if (typeof callback == "function") {
                    callback(tf);
                }
            });

            return;
        }

        var rows = $object.datagrid("getRows");
        var editnum = 0;
        if (opt.editMode == 1 || opt.editMode == 2) {
            for (var i = 0; i < rows.length; i++) {
                if (!(rows[i]["_tag"] === undefined || rows[i]["_tag"] === null)) {
                    editnum++;
                    break;
                }
            }
        }

        if (opt.toolbar === undefined) {
            opt.uppActionState.call($object, s_index, s_row, function (tf) {     //操作节点状态处理接口
                if (typeof callback == "function") {
                    callback(tf);
                }
            });
            return;
        }


        var is_edit = opt.isEdit;
        if (is_edit && !(s_row === null) && opt.wflock) {
            if (s_row["wflock"]) {
                is_edit = false;
            }
        }

        //todo 按钮处理
        if (opt.copy) {
            opt.toolbar.yqEditMenu(((opt.isEdit == false || s_row === null) ? "disable" : "enable"), "copy");
        }

        if (opt.add) {
            opt.toolbar.yqEditMenu((opt.isEdit == false ? "disable" : "enable"), "add");
        }

        if (opt.upp) {
            opt.toolbar.yqEditMenu((s_row === null ? "disable" : "enable"), "upp");
        }

        if (opt.del) {
            var del = false;
            if (!(s_row === null)) {
                if (opt.editMode == 1 || opt.editMode == 2) {
                    if (s_row["_tag"] === undefined
                        || s_row["_tag"] === null
                        || s_row["_tag"] == "U") {
                        if (opt.isdel && opt.isdelEdit == false) {
                            if (s_row[opt.isdel_field] === undefined ||
                                s_row[opt.isdel_field] === null ||
                                s_row[opt.isdel_field] == false) {
                                del = true;
                            }
                        }
                        else {
                            del = true;
                        }
                    }
                    else if (s_row["_tag"] == "A") {
                        del = true;
                    }
                }
                else {
                    if (opt.isdel && opt.isdelEdit == false) {
                        if (s_row[opt.isdel_field] === undefined ||
                            s_row[opt.isdel_field] === null ||
                            s_row[opt.isdel_field] == false) {
                            del = true;
                        }
                    }
                    else {
                        del = true;
                    }
                }
            }
            opt.toolbar.yqEditMenu(((is_edit == false || del == false) ? "disable" : "enable"), "del");
        }

        if (opt.isdel) {
            var isdel1 = false;
            var isdel0 = false;
            if (!(s_row === null)) {
                if (opt.editMode == 1 || opt.editMode == 2) {
                    if (s_row["_tag"] === undefined
                        || s_row["_tag"] === null
                        || s_row["_tag"] == "U") {
                        if (s_row[opt.isdel_field] === undefined ||
                            s_row[opt.isdel_field] === null) {
                            isdel1 = true;
                        } else {
                            if (s_row[opt.isdel_field]) {
                                isdel0 = true;
                            }
                            else {
                                isdel1 = true;
                            }
                        }
                    }
                }
                else {
                    if (s_row[opt.isdel_field] === undefined || s_row[opt.isdel_field] === null) {
                        isdel1 = true;
                    } else {
                        if (s_row[opt.isdel_field]) {
                            isdel0 = true;
                        }
                        else {
                            isdel1 = true;
                        }
                    }
                }
            }
            opt.toolbar.yqEditMenu(((is_edit == false || isdel1 == false) ? "disable" : "enable"), "isdel1");
            opt.toolbar.yqEditMenu(((is_edit == false || isdel0 == false) ? "disable" : "enable"), "isdel0");
        }

        if (opt.state) {
            if (s_row === null || !is_edit) {
                opt.toolbar.yqEditMenu("disable", "state");
            }
            else {
                var state_value = s_row[opt.state_field];
                var state_lists = [];
                for (var i = 0; i < opt.titles.length; i++) {
                    if (opt.titles[i].name == opt.state_field) {
                        state_lists = opt.titles[i].ui_mask.lists;
                        break;
                    }
                }
                if (state_lists === undefined) {
                    state_lists = [];
                }
                opt.toolbar.yqEditMenu((state_lists.length == 0 ? "disable" : "enable"), "state");
                for (var i = 0; i < state_lists.length; i++) {
                    opt.toolbar.yqEditMenu((state_value == state_lists[i].no ? "disable" : "enable"), "state_" + state_lists[i].no);
                }
            }
        }

        if (opt.move) {
            var move = false;
            if (rows.length > 1 && editnum == 0) {
                move = true;
            }

            opt.toolbar.yqEditMenu(((is_edit == false || move == false) ? "disable" : "enable"), "move");
        }

        if (opt.toexcel) {
            var toexcel = false;
            if (rows.length > 1) {
                toexcel = true;
            }

            opt.toolbar.yqEditMenu((toexcel == false ? "disable" : "enable"), "toexcel");
        }

        if (opt.inexcel) {
            opt.toolbar.yqEditMenu((is_edit == false ? "disable" : "enable"), "inexcel");
        }

        if (opt.editMode == 1 || opt.editMode == 2) {
            opt.toolbar.yqEditMenu(((is_edit == false || editnum == 0) ? "disable" : "enable"), "save");
            opt.toolbar.yqEditMenu(((is_edit == false || editnum == 0) ? "disable" : "enable"), "undo");
        }

        if (is_edit && opt.editMode == 1 && !(opt.editIndex === undefined)) {
            opt.toolbar.yqEditMenu("enable", "save");
            opt.toolbar.yqEditMenu("enable", "undo");
        }

        opt.uppActionState.call($object, s_index, s_row, function (tf) {     //操作节点状态处理接口
            if (typeof callback == "function") {
                callback(tf);
            }
        });
    }

    function btn_copy($object) {
        var opt = options($object);
        var s_row = $object.datagrid("getSelected");
        if (s_row === null) {
            return;
        }

        var c_row = $.extend({}, s_row);
        delete c_row[opt.keyId];

        if (opt.editMode == 1) {     //自由编辑
            if (endEditing($object)) {
                c_row["_tag"] = "A";
                appendRow($object, c_row);
                opt.editIndex = $object.datagrid('getRows').length - 1;
                $object.datagrid('selectRow', opt.editIndex)
                    .datagrid('beginEdit', opt.editIndex);
            }

            opt.toolbar.yqEditMenu("enable", "save");
            opt.toolbar.yqEditMenu("enable", "undo");
        }
        else if (opt.editMode == 2 ||
            opt.editMode == 3 ||
            opt.editMode == 4) {   //自由编辑 弹出模板模式，编辑 弹出模板模式
            showEdit($object, "add", c_row);
        }
    }

    function btn_add($object) {
        var opt = options($object);
        var a_row = { "_tag": "A" };
        if (opt.editMode == 1) {     //自由编辑 当前表格编辑
            if (!(opt.bindingKeyId === null) && !(opt.bindingValue === null)) {
                a_row[opt.bindingKeyId] = opt.bindingValue;
            }
            if (!(opt.pKeyId === null) && !(opt.pKeyValue === null)) {
                a_row[opt.pKeyId] = opt.pKeyValue;
            }

            if (endEditing($object)) {
                if (opt.loadDefault) {
                    a_row = $.extend($.yqGetDefaultRow(opt.titles), a_row);
                }

                appendRow($object, a_row, function (b_res) {
                    $object.datagrid('selectRow', b_res.index)
                        .datagrid('beginEdit', b_res.index);
                    opt.toolbar.yqEditMenu("enable", "save");
                    opt.toolbar.yqEditMenu("enable", "undo");
                });
            }
        }
        else if (opt.editMode == 2 ||
            opt.editMode == 3 ||
            opt.editMode == 4) {   //自由编辑 弹出模板模式，编辑 弹出模板模式
            showEdit($object, "add", a_row);
        }
    }

    function btn_upp($object) {
        var opt = options($object);
        var s_row = $object.datagrid("getSelected");
        if (s_row === null) {
            return;
        }

        var s_index = $object.datagrid("getRowIndex", s_row);

        upp_run($object, s_index, s_row);
    }

    function upp_run($object, s_index, s_row) {
        var opt = options($object);
        if (s_row === null || s_index == -1) {
            return;
        }
        else if (opt.editMode == 2) {   //自由编辑 弹出模板模式，编辑 弹出模板模式
            var _tag = s_row["_tag"];
            if (_tag == "D") {
                return;
            }
            showEdit($object, "upp", s_row);
        } else if (opt.editMode == 3 ||
            opt.editMode == 4) {
            showEdit($object, "upp", s_row);
        }
    }

    function showEdit($object, action, row) {
        var opt = options($object);

        if (action == "add") {
            delete row[opt.keyId];

            if (!(opt.bindingKeyId === null) && !(opt.bindingValue === null)) {
                row[opt.bindingKeyId] = opt.bindingValue;
            }
            if (!(opt.pKeyId === null) && !(opt.pKeyValue === null)) {
                row[opt.pKeyId] = opt.pKeyValue;
            }

            var $dg_view = $object.closest('div.datagrid-view');
            var prevent_e = $.getPreventDefault($dg_view);
            opt.prevent_e.clientX = prevent_e.clientX + 40;
            opt.prevent_e.clientY = prevent_e.clientY - $dg_view.height();
            //console.log("opt.prevent_e",opt.prevent_e,$object.closest('div.datagrid-view'));
        }

        var prevent_e = opt.prevent_e;

        var editMode = opt.editMode;
        if (editMode === 4 && !opt.editUrl) {
            opt.editMode = editMode = 3;
        }

        if (editMode == 2 ||
            editMode == 3) {
            var mdiinfo = $.yqGetWindParams();

            if (opt.editType == 1) {
                getEditTitles($object, function (titles) {
                    opt.onBeforeShowEdit.call($object, titles, action, row, function (tf, _titles, _row) {
                        if (tf) {
                            var run_opt = {
                                ajaxUrl: opt.ajaxUrl,
                                mdiinfo: mdiinfo,
                                prevent_e: prevent_e,
                                titles: _titles,
                                action: action,
                                row: $.extend({}, _row),
                                isEdit: opt.isEdit,

                                loadDefault: opt.loadDefault,   //加载默认值
                                blankTag: opt.blankTag,        //值不能为空，标题附加标记

                                title: opt.editTitle,
                                width: opt.editModeW,
                                height: opt.editModeH,

                                dbname: opt.dbname,

                                callback: function (row_) {
                                    showEditAfter($object, action, row_);
                                }
                            };
                            if (window.top == window.self) {
                                $.yqAttrPopEdit(run_opt);
                            }
                            else {
                                window.top.$.yqAttrPopEdit(run_opt);
                            }
                        }
                    });
                });
            } else if (opt.editType == 2) {
                getEditModel($object, function (titles, model) {
                    opt.onBeforeShowEdit.call($object, titles, action, row, function (tf, _titles, _row) {
                        if (tf) {
                            var run_opt = {
                                mdiinfo: mdiinfo,
                                prevent_e: prevent_e,

                                ajaxUrl: opt.ajaxUrl,
                                titles: _titles,
                                model: model,
                                action: action,
                                row: $.extend({}, _row),
                                isEdit: opt.isEdit,

                                loadDefault: opt.loadDefault,   //加载默认值
                                blankTag: opt.blankTag,        //值不能为空，标题附加标记

                                title: opt.editTitle,
                                width: opt.editModeW,
                                height: opt.editModeH,

                                dbname: opt.dbname,

                                callback: function (row_) {
                                    showEditAfter($object, action, row_);
                                }
                            };

                            if (window.top == window.self) {
                                $.yqFormPopEdit(run_opt);
                            }
                            else {
                                window.top.$.yqFormPopEdit(run_opt);
                            }
                        }
                    });
                });
            }
        } else if (editMode == 4) {
            opt.onBeforeShowEdit.call($object, opt.titles, action, row, function (tf, _titles, _row) {
                if (tf) {
                    if (opt.$row === undefined) {
                        getEditModel($object, function (titles, model) {
                            showEditModel(_row, titles, model);
                        });
                    } else {
                        var s_row = $.extend({}, opt.$row);
                        delete opt.$row;
                        showEditModel(s_row);
                    }
                }
            });
        }

        function showEditModel(row, titles, model) {
            var mdiinfo = $.yqGetWindParams();
            prevent_e.p_target = $object;

            if (!(model === undefined)) {
                prevent_e.titles = titles;
                prevent_e.model = model;
                prevent_e.dbname = opt.dbname;
            }
            prevent_e.action = action;
            prevent_e.row = row;
            if (!(opt.$type === undefined)) {
                prevent_e.type = opt.$type;
                delete opt.$type;
            }

            var editUrl = opt.editUrl;
            if (!(editUrl === null) && $.urlParam(editUrl, "appno") == "") {
                var appno = $.urlRequest("appno");
                if (appno != "") {
                    var menuno = $.urlRequest("menuno");
                    editUrl += (editUrl.indexOf("?") == -1 ? "?" : "&") + "appno=" + appno + "&menuno=" + menuno;
                }
            }

            var edit_pops = {
                prevent_e: prevent_e,
                mdiinfo: mdiinfo,
                title: opt.editTitle,
                width: opt.editModeW,
                height: opt.editModeH,
                maximiz: opt.editMaximiz,
                url: editUrl,

                onOpen: function () {
                    //console.log("onOpen");
                },
                onBeforeClose: function () {
                    //console.log("onBeforeClose");
                    return true;
                },
            };

            if (window.top == window.self) {
                $.yqWinPopEdit(edit_pops);
            }
            else {
                window.top.$.yqWinPopEdit(edit_pops);
            }
        }
    }

    function showEditAfter($object, action, row_) {
        var opt = options($object);

        if (opt.editMode == 2) {
            setForienKeys($object, [row_], function () {
                if (action == "add") {
                    row_["_tag"] = "A";
                    appendRow($object, row_, function (res_) {
                        uppActionState($object, res_.index, res_.row, function (tf) { });
                    });
                } else if (action == "upp") {
                    var _tag = row_["_tag"];
                    if (_tag == "A") {
                        row_["_tag"] = "A";
                    }
                    else {
                        delete row_["_tag"];
                        var s_index = -1;
                        var rows_ = $object.datagrid("getRows");
                        for (let j = 0; j < rows_.length; j++) {
                            if (rows_[j][opt.keyId] == row_[opt.keyId]) {
                                s_index = j;
                                break;
                            }
                        }
                        if ($.isRowEqual(row_, opt.data.rows[s_index]) == false) {
                            row_["_tag"] = "U";
                        }
                        else {
                            row_["_tag"] = null;
                        }
                    }

                    //$object.datagrid("updateRow", { index: s_index, row: res.row });
                    updateRow($object, row_, function (res_) {
                        uppActionState($object, res_.index, res_.row, function (tf) { });
                    });
                }
            });
        } else if (opt.editMode == 3) {
            rowEdit($object, action, row_);
        }
    }

    //属性编辑模式
    function getEditTitles($object, callback) {
        var opt = options($object);
        if (typeof opt.edit_titles != "undefined") {
            callback(opt.edit_titles);
        }
        else if (opt.tempno == opt.editModeNo) {
            opt.edit_titles = opt.titles;
            callback(opt.edit_titles);
        }
        else {
            var pp_opt = {
                ajaxUrl: opt.ajaxUrl,
                dbname: opt.dbname,                //数据库
                tbname: opt.tbname,                //表
                tempno: opt.editModeNo
            };

            if (typeof opt._appno != undefined) {
                pp_opt.ctrlid = opt._ctrlid;
                pp_opt.appno = opt._appno;
                pp_opt.menuno = opt._menuno;
            }

            $.yqTbTitle(pp_opt, function (res) {
                if (res.error == 0) {
                    opt.edit_titles = $.yqFmUiTitle(res.titles);
                }
                else {
                    //console.log(res);
                    opt.edit_titles = opt.titles;
                }

                callback(opt.edit_titles);
            })
        }
    }

    //取得移动编辑模板
    function getSeekTitles($object, callback) {
        var opt = options($object);
        if (typeof opt.seek_titles != "undefined") {
            callback(opt.seek_titles);
        }
        else if (opt.tempno == opt.seekNo) {
            opt.seek_titles = opt.titles;
            callback(opt.seek_titles);
        }
        else {
            var pp_opt = {
                ajaxUrl: opt.ajaxUrl,
                dbname: opt.dbname,                //数据库
                tbname: opt.tbname,                //表
                tempno: opt.seekNo
            };

            if (typeof opt._appno != undefined) {
                pp_opt.ctrlid = opt._ctrlid;
                pp_opt.appno = opt._appno;
                pp_opt.menuno = opt._menuno;
            }

            $.yqTbTitle(pp_opt, function (res) {
                if (res.error == 0) {
                    opt.seek_titles = $.yqFmUiTitle(res.titles);
                }
                else {
                    opt.seek_titles = opt.titles;
                }

                callback(opt.seek_titles);
            })
        }
    }

    //form编辑模式 begin
    function getEditModel($object, callback) {
        var opt = options($object);
        if (typeof opt.edit_titles != "undefined") {
            getEditModel_($object, function (model) {
                callback(opt.edit_titles, model);
            });
        }
        else if (opt.tempno == -1) {
            opt.edit_titles = opt.titles;
            getEditModel_($object, function (model) {
                callback(opt.edit_titles, model);
            });
        }
        else {
            var pp_opt = {
                ajaxUrl: opt.ajaxUrl,
                dbname: opt.dbname,                //数据库
                tbname: opt.tbname,                //表
                tempno: -1
            };

            if (typeof opt._appno != undefined) {
                pp_opt.ctrlid = opt._ctrlid;
                pp_opt.appno = opt._appno;
                pp_opt.menuno = opt._menuno;
            }

            $.yqTbTitle(pp_opt, function (res) {
                if (res.error == 0) {
                    opt.edit_titles = $.yqFmUiTitle(res.titles);
                } else {
                    //console.log(res);
                    opt.edit_titles = opt.titles;
                }

                getEditModel_($object, function (model) {
                    callback(opt.edit_titles, model);
                });
            })
        }
    }

    function getEditModel_($object, callback) {
        var opt = options($object);
        if (typeof opt.edit_model != "undefined") {
            callback(opt.edit_model);
        }
        else if (opt.tempno == opt.editModeNo) {
            opt.edit_model = JSON.stringify(opt.titles);
            callback(opt.edit_model);
        }
        else {
            var pp_opt = {
                ajaxUrl: opt.ajaxUrl,
                dbname: opt.dbname,                //数据库
                tbname: opt.tbname,                //表
                tempno: opt.editModeNo
            };

            if (typeof opt._appno != undefined) {
                pp_opt.ctrlid = opt._ctrlid;
                pp_opt.appno = opt._appno;
                pp_opt.menuno = opt._menuno;
            }

            $.yqTbModel(pp_opt, function (res) {
                if (res.error == 0) {
                    opt.edit_model = res.model;
                } else {
                    //console.log(res);
                    opt.edit_model = JSON.stringify(opt.titles);
                }

                callback(opt.edit_model);
            })
        }
    }
    //form编辑模式  end

    function del_run($object, index) {
        var opt = options($object);
        $object.datagrid("selectRow", index);

        btn_del($object);
    }

    function btn_del($object) {
        var opt = options($object);
        var s_row = $object.datagrid("getSelected");
        if (s_row === null) {
            return;
        }
        var s_index = $object.datagrid("getRowIndex", s_row);
        if (opt.editMode == 1 || opt.editMode == 2) {     //自由编辑
            if (s_row["_tag"] == "A") {
                $object.datagrid("deleteRow", s_index);

                var s_row_ = $object.datagrid("getSelected");
                var s_index_ = -1;
                if (!(s_row_ === null)) {
                    s_index_ = $object.datagrid("getRowIndex", s_row_);
                }

                uppActionState($object, s_index_, s_row_, function (tf) { });
            }
            else {
                var s_row = $.extend({}, opt.data.rows[s_index]);
                s_row["_tag"] = "D";
                $object.datagrid("updateRow", { index: s_index, row: s_row });
                uppActionState($object, s_index, opt.data.rows[s_index], function (tf) { });
            }
        } else if (opt.editMode == 3 ||
            opt.editMode == 4) {
            var d_rows = [];
            var row = {};
            row[opt.keyId] = s_row[opt.keyId];
            d_rows.push({ action: "del", row: row });
            if (opt.editAlert && opt.innerEdit_) {
                $.yqConfirm("删除", "是否确认?",
                    function (r) {
                        if (r) {
                            dataAction($object, d_rows);
                        }
                    });
            } else {
                dataAction($object, d_rows);
            }
        }
    }

    function btn_save($object) {
        var opt = options($object);
        if (opt.editMode == 1) {   //自由编辑
            if (endEditing($object) == false) {
                return;
            }
        }

        var rows = $object.datagrid("getRows");
        var d_rows = [];
        for (var i = 0; i < rows.length; i++) {
            if (rows[i]["_tag"] == "A") {
                var row_ = $.extend({}, rows[i]);
                delete row_["_tag"];
                delete row_[opt.keyId];
                d_rows.push({ action: "add", row: row_ });
            }
            else if (rows[i]["_tag"] == "U") {
                var row_ = $.extend(opt.data.rows[i], rows[i]);
                delete row_["_tag"];
                d_rows.push({ action: "upp", row: row_ });
            }
            else if (rows[i]["_tag"] == "D") {
                var row = {};
                row[opt.keyId] = rows[i][opt.keyId];
                d_rows.push({ action: "del", row: row });
            }
        }

        opt.beforeSave.call($object, d_rows,
            function (tf, _d_rows) {
                if (tf && _d_rows.length > 0) {
                    dataAction($object, _d_rows);
                }
            });
    }

    function rowEdit($object, action, row) {
        var opt = options($object);

        delete row["_tag"];
        if (row == "add") {
            delete row[opt.keyId];
            if (!(opt.bindingKeyId === null) && !(opt.bindingValue === null)) {
                row[opt.bindingKeyId] = opt.bindingValue;
            }
            if (!(opt.pKeyId === null) && !(opt.pKeyValue === null)) {
                row[opt.pKeyId] = opt.pKeyValue;
            }
        }

        var d_rows = [];
        var m_row = {
            action: action,
            row: row
        }
        d_rows.push(m_row);
        dataAction($object, d_rows);
    }

    function btn_undo($object) {
        var opt = options($object);
        if (opt.editMode == 1 || opt.editMode == 2) {     //自由编辑
            setData($object, opt.data)
        }
    }

    function btn_isdel($object, isdel) {
        var opt = options($object);
        var s_row = $object.datagrid("getSelected");
        if (s_row === null) {
            return;
        }

        var row = {};
        row[opt.keyId] = s_row[opt.keyId];
        row[opt.isdel_field] = isdel;
        var d_rows = [{
            "action": "upp_",
            "row": row
        }];
        dataAction($object, d_rows);
    }

    function btn_state($object, params) {
        var opt = options($object);
        console.log(params)

        var s_row = $object.datagrid("getSelected");
        if (s_row === null) {
            return;
        }

        var row = {};
        row[opt.keyId] = s_row[opt.keyId];
        row[opt.state_field] = params.no;
        var d_rows = [{
            "action": "upp_",
            "row": row
        }];
        dataAction($object, d_rows);
    }

    function btn_move($object) {
        var opt = options($object);

        if (opt.editMode == 1) {     //自由编辑
            if (!endEditing($object)) {
                return;
            }
        }

        var rows = [];
        for (let i = 0; i < opt.data.rows.length; i++) {
            rows.push($.extend({}, opt.data.rows[i]));
        }

        getMoveTitles($object, function (titles) {
            opt.onBeforeShowEdit.call($object, titles, "move", rows,
                function (tf, _titles, _rows) {
                    if (tf) {
                        var mdiinfo = $.yqGetWindParams();
                        var move_opt = {
                            prevent_e: opt.prevent_e,
                            mdiinfo: mdiinfo,
                            //title: $.fn.yqUiExtText.DialogMoveTitle,
                            width: opt.moveModeW,
                            height: opt.moveModeH,

                            ajaxUrl: opt.ajaxUrl,
                            titles: _titles,
                            rows: _rows,
                            callback: function (_rows) {
                                var d_rows = [];
                                var ids = [];
                                var ids_ = [];
                                for (var i = 0; i < _rows.length; i++) {
                                    ids.push(_rows[i][opt.keyId]);
                                }

                                for (var j = 0; j < rows.length; j++) {
                                    ids_.push(rows[j][opt.keyId]);
                                }

                                if (JSON.stringify(ids) == JSON.stringify(ids_)) {
                                    return;
                                }

                                var m_row = {
                                    "action": "move",
                                    "row":
                                    {
                                        "ids": ids
                                    }
                                }
                                if (!(opt.bindingKeyId === null) && !(opt.bindingValue === null)) {
                                    m_row.row["binding_field"] = opt.bindingKeyId;
                                    m_row.row[opt.bindingKeyId] = opt.bindingValue;
                                }
                                if (!(opt.pKeyId === null) && !(opt.pKeyValue === null)) {
                                    m_row.row["pid_field"] = opt.pKeyId;
                                    m_row.row[opt.pKeyId] = opt.pKeyValue;
                                }
                                d_rows.push(m_row);

                                dataAction($object, d_rows);
                            }
                        };

                        if (window.self == window.top) {
                            $.yqRowsPopMove(move_opt);
                        }
                        else {
                            window.top.$.yqRowsPopMove(move_opt);
                        }
                    }
                })
        })
    }

    function btn_toexcel($object) {
        var opt = options($object);
        var rows = [];
        for (let i = 0; i < opt.data.rows.length; i++) {
            var row = $.extend({}, opt.data.rows[i]);
            for (var j = 0; j < opt.titles.length; j++) {
                var para = $.extend({}, opt.titles[j]);
                para.value = row[opt.titles[j].name];
                if (para.ui_type == 3) { //checkbox
                    row[opt.titles[j].name] = para.value;
                } else if (para.ui_type == 6 ||
                    para.ui_type == 7 ||
                    para.ui_type == 8 ||
                    para.ui_type == 13 ||
                    para.ui_type == 14
                ) {
                    row[opt.titles[j].name] = para.value;
                    row[opt.titles[j].name + "_val"] = $.yqPgFormatter.call({ p_target: $object }, para);
                } else {
                    row[opt.titles[j].name] = $.yqPgFormatter.call({ p_target: $object }, para);
                }
            }
            rows.push(row);
        }

        var row_title = [];
        for (var i = 0; i < opt.titles.length; i++) {
            var para = opt.titles[i];
            row_title.push({
                name: para.name,
                title: para.ui_title,
                width: para.ui_width
            });
            if (para.ui_type == 6 ||
                para.ui_type == 7 ||
                para.ui_type == 8 ||
                para.ui_type == 13 ||
                para.ui_type == 14
            ) {
                row_title.push({
                    name: para.name + "_val",
                    title: para.ui_title + "_val",
                    width: para.ui_width
                });
            }
        }

        var mergeCells = [];
        console.log(row_title, rows);
        opt.beforeToExcel.call($object, row_title, rows, mergeCells,
            function (row_title_, rows_, mergeCells_) {
                $.yqDataToExcel({
                    filename: opt.excelName + ".xls",
                    header: row_title_,
                    data: rows_,
                    mergeCells: mergeCells_
                }, function (res) {
                    //console.log(res);
                });
            });
    }

    function btn_inexcel($object) {

    }

    //取得移动编辑模板
    function getMoveTitles($object, callback) {
        var opt = options($object);
        if (typeof opt.move_titles != "undefined") {
            callback(opt.move_titles);
        }
        else if (opt.tempno == opt.moveModeNo) {
            opt.move_titles = opt.titles;
            callback(opt.move_titles);
        }
        else {
            var pp_opt = {
                ajaxUrl: opt.ajaxUrl,
                dbname: opt.dbname,                //数据库
                tbname: opt.tbname,                //表
                tempno: opt.moveModeNo
            };

            if (typeof opt._appno != undefined) {
                pp_opt.ctrlid = opt._ctrlid;
                pp_opt.appno = opt._appno;
                pp_opt.menuno = opt._menuno;
            }

            $.yqTbTitle(pp_opt, function (res) {
                if (res.error == 0) {
                    opt.move_titles = $.yqFmUiTitle(res.titles);
                }
                else {
                    //console.log(res);
                    opt.move_titles = opt.titles;
                }

                callback(opt.move_titles);
            })
        }
    }

    function dataAction($object, rows) {
        var opt = options($object);
        //$.yqFmToData(rows[i], opt.titles)
        var a_rows = [];
        for (var i = 0; i < rows.length; i++) {
            var _row = { action: rows[i].action };
            if (rows[i].action == "add" || rows[i].action == "upp") {
                _row.row = $.yqFmToData(rows[i].row, opt.titles,
                    (opt.fk_rows === undefined ? [] : opt.fk_rows), true);
            }
            else {
                _row.row = rows[i].row;
            }

            a_rows.push(_row);
        }

        //console.log("a_rows",a_rows);

        opt.beforeDataAction.call($object, a_rows,
            function (tf, _a_rows) {
                if (tf) {
                    var file_titles = getFile_edit_titles();
                    //保存前，文件上传处理
                    if (file_titles.length > 0) {
                        $.yqFilesUpload(file_titles, _a_rows, function (__a_rows) {
                            for (let jj = 0; jj < __a_rows.length; jj++) {
                                for (let ii = 0; ii < file_titles.length; ii++) {
                                    rows[jj].row[file_titles[ii].field_name] = __a_rows[jj].row[file_titles[ii].field_name];
                                }
                            }

                            toDB(__a_rows, file_titles);
                        })
                    } else {
                        toDB(_a_rows, null);
                    }
                }
            });

        //获取文件字段
        function getFile_edit_titles() {
            if (opt.f_edit_titles === undefined) {
                //文件处理
                opt.f_edit_titles = [];
                if (typeof opt.edit_titles === "object") {
                    for (let i = 0; i < opt.edit_titles.length; i++) {
                        if (opt.edit_titles[i].ui_type == 18 ||
                            opt.edit_titles[i].ui_type == 19) {
                            opt.f_edit_titles.push({
                                field_type: opt.edit_titles[i].ui_type,
                                field_name: opt.edit_titles[i].name,
                                sto_type: opt.edit_titles[i].ui_mask.storageType,
                                sto_name: (opt.edit_titles[i].ui_mask.storageType == 1 ? opt.dbname : opt.edit_titles[i].ui_mask.storageName),
                                chunk: opt.edit_titles[i].ui_mask.chunk
                            });
                        }
                    }
                } else {
                    for (let i = 0; i < opt.titles.length; i++) {
                        if (opt.titles[i].ui_type == 18 ||
                            opt.titles[i].ui_type == 19) {
                            opt.f_edit_titles.push({
                                field_type: opt.titles[i].ui_type,
                                field_name: opt.titles[i].name,
                                sto_type: opt.titles[i].ui_mask.storageType,
                                sto_name: (opt.titles[i].ui_mask.storageType == 1 ? opt.dbname : opt.titles[i].ui_mask.storageName),
                                chunk: opt.titles[i].ui_mask.chunk
                            });
                        }
                    }
                }
            }

            return opt.f_edit_titles;
        }

        function toDB(a_rows, file_params) {
            var a_opt = {
                ajaxUrl: opt.ajaxUrl,
                dbname: opt.dbname,                //数据库
                tbname: opt.tbname,                //表
                rows: a_rows,
            };

            if (typeof opt._appno != undefined) {
                a_opt.ctrlid = opt._ctrlid;
                a_opt.appno = opt._appno;
                a_opt.menuno = opt._menuno;
            }

            if (typeof file_params == "object") {
                a_opt.fileparm = file_params;
            }

            $.yqDbAction(a_opt,
                function (res) {
                    if (res.error == 0) {
                        if (!(opt.editMode == 1 || opt.editMode == 2)) {
                            var rows__ = [];
                            for (var i = 0; i < res.rows.length; i++) {
                                if (res.rows[i].error == 0) {
                                    if (res.rows[i].action == "add") {
                                        a_opt.rows[i].row[opt.keyId] = res.rows[i][opt.keyId];
                                        rows__.push(a_opt.rows[i].row);
                                    }
                                    else if (res.rows[i].action == "upp") {
                                        rows__.push(a_opt.rows[i].row);
                                    }
                                }
                            }

                            if (rows__.length == 0) {
                                dataAction_($object, a_opt.rows, res);
                            } else {
                                setForienKeys($object, rows__, function () {
                                    dataAction_($object, a_opt.rows, res);
                                });
                            }
                        } else {
                            dataAction_($object, a_opt.rows, res);
                        }
                    } else {
                        $.yqMessager("error", res.info + "[" + res.error + "]");
                    }
                });
        }
    }

    function dataAction_($object, rows, res) {
        var opt = options($object);

        if (res.error == 0 && res.rows.length == rows.length) {
            var error = "";

            //for 添加、修改后更新数据库数据
            var editList = [];

            //处理add错误的情况
            var adds = 0;
            var addslist = [];

            for (var i = 0; i < res.rows.length; i++) {
                if (res.rows[i].error == 0) {
                    if (res.rows[i].action == "add") {
                        rows[i].row[opt.keyId] = res.rows[i][opt.keyId];
                        appendRow_data($object, rows[i].row);

                        editList.push(rows[i].row[opt.keyId]);
                    }
                    else if (res.rows[i].action == "del") {
                        deleteRow_data($object, rows[i].row);
                    }
                    else if (res.rows[i].action == "move") {
                        moveRow_data($object, rows[i].row.ids);
                    }
                    else {
                        updateRow_data($object, rows[i].row);

                        editList.push(rows[i].row[opt.keyId]);
                    }
                } else {
                    if (res.rows[i].action == "add") {
                        addslist.push(adds);
                    }

                    error += "line:" + (i + 1) + ":" + res.rows[i].info
                }

                if (res.rows[i].action == "add") {
                    adds++;
                }
            }

            if (error != "") {
                $.yqMessager("error", error);
            } else {
                $.yqMessager("success", "执行成功。");
            }

            if (opt.editMode == 1 || opt.editMode == 2) {   //自由编辑 弹出模板模式
                adds = 0;
                var _rows = $object.datagrid('getRows');
                for (var j = (_rows.length - 1); j >= 0; j--) {
                    if (_rows[j]["_tag"] == "A") {
                        var hasErr = false;
                        for (var l = 0; l < addslist.length; l++) {
                            if (adds == addslist[l]) {
                                hasErr = true;
                            }
                        }

                        if (!hasErr) {
                            $object.datagrid("deleteRow", j);
                        }

                        adds++;
                    }
                }
            } else if (error != "") {
                if (rows[0].action == "add" ||
                    rows[0].action == "upp") {

                    showEdit($object, rows[0].action, rows[0].row, function (tf_, row_) {
                        if (tf_) {
                            var d_rows = [];
                            var m_row = {
                                action: res.rows[0].action,
                                row: row_
                            }
                            d_rows.push(m_row);
                            dataAction($object, d_rows);
                        }
                    });

                    return;
                }
            }

            if (opt.isPage) {
                var pager = $object.datagrid('getPager');
                pager.pagination('refresh', {
                    total: opt.data.recordCount,    //;
                    pageNumber: opt.data.pageNo
                });
            }

            if (opt.editLoadData && editList.length > 0) {
                editLoadData($object, editList, 0);
            }

            uppActionState($object);
        }
        else {
            $.yqMessager("error", res.info + "[" + res.error + "]");
        }

        opt.afterDataAction.call($object, rows, res);
    }

    function editLoadData($object, editList, index) {
        if (editList.length == index) {
            return;
        }
        var opt = options($object);
        var opt_row = {
            ajaxUrl: opt.ajaxUrl,
            dbname: opt.dbname,                //数据库
            tbname: opt.tbname,                       //表
            keyid: opt.keyId,
            keyval: editList[index]
        };
        if (typeof opt._appno != undefined) {
            opt_row.ctrlid = opt._ctrlid;
            opt_row.appno = opt._appno;
            opt_row.menuno = opt._menuno;
        }

        $.yqDbTbRow(opt_row, function (res) {
            if (res.error == 0) {
                updateRow_data($object, res.row);
            } else {
                console.log(res);
            }

            editLoadData($object, editList, index + 1);
        })
    }

    //todata
    function appendRow_data($object, row) {
        var opt = options($object);
        var _row = $.yqFmToView(row, opt.titles);
        opt.data.rows.push(_row);
        appendRow($object, $.extend({}, _row));
    }

    //toUI
    function appendRow($object, row, callback) {
        var opt = options($object);
        $object.datagrid('appendRow', row);

        if (opt.isPage) {
            var pager = $object.datagrid('getPager');
            pager.pagination('refresh', {
                total: opt.data.recordCount,    //;
                pageNumber: opt.data.pageNo
            });
        }
        var rows = $object.datagrid("getRows");
        if (typeof callback == "function") {
            $object.datagrid("selectRow", (rows.length - 1));
            callback({ "action": "add", "index": (rows.length - 1), "row": rows[rows.length - 1] })
        }
        if (opt.editMode == 3 || opt.editMode == 4) {
            $object.datagrid("selectRow", rows.length - 1);
        }
    }

    //todata
    function updateRow_data($object, row) {
        var opt = options($object);
        var _has = false;
        for (var i = 0; i < opt.data.rows.length; i++) {
            if (row[opt.keyId] == opt.data.rows[i][opt.keyId]) {
                var _row = $.extend({}, row);
                _row = $.yqFmToView(_row, opt.titles);
                opt.data.rows[i] = _row;
                _has = true;
                break;
            }
        }

        if (_has) {
            updateRow($object, $.extend({}, _row));
        }
    }

    //toUI
    function updateRow($object, row, callback) {
        var opt = options($object);

        var rows = $object.datagrid('getRows');
        for (var i = 0; i < rows.length; i++) {
            if (rows[i][opt.keyId] == row[opt.keyId]) {
                var _tag = row["_tag"];
                if ((_tag === undefined || _tag === null || _tag == "")
                    && typeof rows[i]["_tag"] != "undefined") {
                    _tag = null;
                }
                //输入补全
                //row = $.yqFmToView(row, opt.titles);
                row["_tag"] = _tag;

                $object.datagrid("updateRow", { index: i, row: row });
                $object.datagrid('refreshRow', i);

                if (typeof callback == "function") {
                    $object.datagrid("selectRow", i);
                    callback({ "action": "upp", "index": i, "row": $object.datagrid("getRows")[i] })
                }

                break;
            }
        }
    }

    function moveRow_data($object, ids) {
        var opt = options($object);
        var data_ = $.extend({}, opt.data);
        var rows = [];
        var rows_ = [];
        for (var i = 0; i < ids.length; i++) {
            for (var j = 0; j < opt.data.rows.length; j++) {
                if (ids[i] == opt.data.rows[j][opt.keyId]) {
                    opt.data.rows[j]["queue"] = (i + 1);
                    rows.push(opt.data.rows[j]);
                    rows_.push($.extend({}, opt.data.rows[j]))
                    break;
                }
            }
        }

        opt.data.rows = rows;
        data_.rows = rows_;

        $object.datagrid("loadData", data_);
    }

    //todata
    function deleteRow_data($object, row) {
        var opt = options($object);
        var _has = false;
        for (var i = 0; i < opt.data.rows.length; i++) {
            if (row[opt.keyId] == opt.data.rows[i][opt.keyId]) {
                opt.data.rows.splice(i, 1);
                _has = true;
                break;
            }
        }

        if (_has) {
            deleteRow($object, row);
        }
    }

    //toUI
    function deleteRow($object, row) {
        var opt = options($object);
        var rows = $object.datagrid('getRows');
        for (var i = 0; i < rows.length; i++) {
            if (rows[i][opt.keyId] == row[opt.keyId]) {
                deleteRow_($object, i);
                break;
            }
        }
    }

    function deleteRow_($object, i) {
        var opt = options($object);
        $object.datagrid("deleteRow", i);
        var index = -1;
        if (i < $object.datagrid("getRows").length) {
            $object.datagrid('selectRow', i);
            index = i;
        } else if (i > 0) {
            $object.datagrid('selectRow', i - 1);
            index = i - 1;
        }

        opt.onClickRow.call($object, index, $object.datagrid('getSelected'));
    }

})(jQuery);